package concordia.comp6231.client;
// A sample Java IDL object client application.
import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.SwingUtilities;

import org.omg.CORBA.ORB;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;

import concordia.comp6231.boxOfficeService.MyService;
import concordia.comp6231.boxOfficeService.MyServiceHelper;


/**
 * Client GUI client
 * 
 * @author osama
 * 
 */
public class MyServiceClient extends javax.swing.JFrame {
	static MyService serviceImpl;
	static ORB orb;
	final String HSEP = "---------------------------------------------------------------------------------------";

	private static final long serialVersionUID = 1L;
	private javax.swing.JLabel userIDFieldLabel;
	private javax.swing.JTextField userIDTextField;
	private javax.swing.JLabel showIDFieldLabel;
	private javax.swing.JTextField showIDTextField;
	private javax.swing.JButton checkButton;
	private javax.swing.JLabel availableTicketsLabel;
	private javax.swing.JLabel ticketsFieldLabel;
	private javax.swing.JTextField ticketsTextField;

	private javax.swing.JButton reserveButton;
	private javax.swing.JButton cancelButton;
	private javax.swing.JButton exchangeButton;

	protected static String rmiRegistryHost;
	protected static String rmiRegistryPort;

	private javax.swing.JLabel exchangeSeparatorLabel;
	private javax.swing.JLabel exchangeLabel;
	private javax.swing.JLabel exchangeReservedShowLabel;
	private javax.swing.JLabel exchangeDesiredShowLabel;
	private javax.swing.JLabel exchangeReservedTicketsLabel;
	private javax.swing.JLabel exchangeDesiredTicketsLabel;
	private javax.swing.JTextField exchangeReservedShowTextField;
	private javax.swing.JTextField exchangeDesiredShowTextField;
	private javax.swing.JTextField exchangeReservedTicketsTextField;
	private javax.swing.JTextField exchangeDesiredTicketsTextField;

	private javax.swing.JLabel resultField;
	private javax.swing.JLabel resultSeparator;

	/**
	 * Creates new form CustomerClient
	 **/
	public MyServiceClient() {
		initComponents();
	}

	/**
	 * Initializes the form and its components.
	 */
	private void initComponents() {
		userIDFieldLabel = new JLabel();
		userIDTextField = new JTextField();
		showIDFieldLabel = new JLabel();
		showIDTextField = new JTextField();
		checkButton = new JButton();
		availableTicketsLabel = new JLabel();
		ticketsFieldLabel = new JLabel();
		ticketsTextField = new JTextField();
		reserveButton = new JButton();
		cancelButton = new JButton();
		exchangeButton = new JButton();
		resultField = new JLabel();
		resultSeparator = new JLabel();
		exchangeLabel = new JLabel();
		exchangeSeparatorLabel = new JLabel();
		exchangeReservedShowLabel = new JLabel();
		exchangeDesiredShowLabel = new JLabel();
		exchangeReservedTicketsLabel = new JLabel();
		exchangeDesiredTicketsLabel = new JLabel();
		exchangeReservedShowTextField = new JTextField();
		exchangeDesiredShowTextField = new JTextField();
		exchangeReservedTicketsTextField = new JTextField();
		exchangeDesiredTicketsTextField = new JTextField();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setTitle("DTRS Client");
		showIDFieldLabel.setText("Show ID:");
		userIDFieldLabel.setText("User ID:");
		ticketsFieldLabel.setText("Number Of Tickets:");
		availableTicketsLabel.setText("-");
		exchangeSeparatorLabel.setText(HSEP);
		exchangeLabel.setText("Exchange tickets:");
		exchangeReservedShowLabel.setText("Reserved Show ID:");
		exchangeReservedTicketsLabel.setText("Reserved Tickets:");
		exchangeDesiredShowLabel.setText("Desired Show ID:");
		exchangeDesiredTicketsLabel.setText("Desired Tickets:");
		resultSeparator.setText(HSEP);

		checkButton.setText("Check Available Tickets");
		checkButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				checkButtonActionPerformed(evt);
			}
		});
		reserveButton.setText("Reserve Tickets");
		reserveButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				reserveButtonActionPerformed(evt);
			}
		});
		cancelButton.setText("Cancel Tickets");
		cancelButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				cancelButtonActionPerformed(evt);
			}
		});
		exchangeButton.setText("Exchange Tickets");
		exchangeButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				exchangeButtonActionPerformed(evt);
			}
		});
		
        GroupLayout layout = new GroupLayout(getContentPane());
        layout.setAutoCreateContainerGaps(true);
        layout.setAutoCreateGaps(true);
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
            	.addContainerGap(27, Short.MAX_VALUE)
                .addGroup(
					layout.createParallelGroup(GroupLayout.Alignment.LEADING)
					.addGroup(layout.createSequentialGroup().addComponent(showIDFieldLabel).addComponent(showIDTextField))
					.addGroup(layout.createSequentialGroup().addComponent(userIDFieldLabel).addComponent(userIDTextField))
					.addGroup(layout.createSequentialGroup().addComponent(checkButton).addComponent(availableTicketsLabel))
					.addGroup(layout.createSequentialGroup().addComponent(ticketsFieldLabel).addComponent(ticketsTextField))
					.addGroup(layout.createSequentialGroup().addComponent(reserveButton).addComponent(cancelButton))
					.addComponent(exchangeSeparatorLabel)
					.addComponent(exchangeLabel)
					.addGroup(layout.createSequentialGroup().addComponent(exchangeReservedShowLabel).addComponent(exchangeReservedShowTextField))
					.addGroup(layout.createSequentialGroup().addComponent(exchangeReservedTicketsLabel).addComponent(exchangeReservedTicketsTextField))
					.addGroup(layout.createSequentialGroup().addComponent(exchangeDesiredShowLabel).addComponent(exchangeDesiredShowTextField))
					.addGroup(layout.createSequentialGroup().addComponent(exchangeDesiredTicketsLabel).addComponent(exchangeDesiredTicketsTextField))
					.addComponent(exchangeButton)
					.addComponent(resultSeparator)
					.addComponent(resultField)
                 ).addContainerGap(27, Short.MAX_VALUE))
        );
 
        layout.setVerticalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(
				layout.createSequentialGroup().addContainerGap().addContainerGap(21, Short.MAX_VALUE)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(userIDFieldLabel).addComponent(userIDTextField))
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(showIDFieldLabel).addComponent(showIDTextField))
				.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(checkButton).addComponent(availableTicketsLabel))
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(ticketsFieldLabel).addComponent(ticketsTextField))
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(reserveButton).addComponent(cancelButton))
				.addComponent(exchangeSeparatorLabel)
				.addComponent(exchangeLabel)
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(exchangeReservedShowLabel).addComponent(exchangeReservedShowTextField))
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(exchangeReservedTicketsLabel).addComponent(exchangeReservedTicketsTextField))
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(exchangeDesiredShowLabel).addComponent(exchangeDesiredShowTextField))
				.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(exchangeDesiredTicketsLabel).addComponent(exchangeDesiredTicketsTextField))
				.addComponent(exchangeButton)
				.addComponent(resultSeparator)
				.addComponent(resultField)
				.addContainerGap(27, Short.MAX_VALUE))
        );
		Dimension screenSize = new Dimension(Toolkit.getDefaultToolkit().getScreenSize());
		Dimension windowSize = new Dimension(700, 500);
		setSize(windowSize);
		int left = screenSize.width/2 - windowSize.width/2;
		int top = screenSize.height/2 - windowSize.height/2;
		setLocation(left, top);
        pack();
	}

	private boolean validateUserAndShowFields() {
		return validateUserField() && validateShowField();
	}

	private boolean validateUserField() {
		if (userIDTextField.getText().isEmpty()) {
			JOptionPane.showMessageDialog(this, "Please enter your UserID");
			return false;
		}
		return true;
	}

	private boolean validateShowField() {
		if (showIDTextField.getText().isEmpty()) {
			JOptionPane.showMessageDialog(this, "Please provide a ShowID");
			return false;
		}
		return true;
	}

	private boolean validateTicketsField() {
		if (ticketsTextField.getText().isEmpty()) {
			JOptionPane.showMessageDialog(this,
					"Please provide number of tickets");
			return false;
		}
		try {
			Integer.parseInt(ticketsTextField.getText());
		} catch (NumberFormatException e) {
			JOptionPane.showMessageDialog(this, "Invalid tickets number value!");
			return false;
		}
		return true;
	}

	private boolean validateExchangeFields() {
		if (exchangeReservedShowTextField.getText().isEmpty()) {
			JOptionPane.showMessageDialog(this,
					"Please provide Reserved Show ID");
			return false;
		}
		try {
			Integer.parseInt(exchangeReservedTicketsTextField.getText());
		} catch (NumberFormatException e) {
			JOptionPane.showMessageDialog(this, "Invalid Reserved Tickets number value!");
			return false;
		}
		if (exchangeDesiredShowTextField.getText().isEmpty()) {
			JOptionPane.showMessageDialog(this, "Please provide Desired Show ID");
			return false;
		}
		try {
			Integer.parseInt(exchangeDesiredTicketsTextField.getText());
		} catch (NumberFormatException e) {
			JOptionPane.showMessageDialog(this, "Invalid Desired Tickets number value!");
			return false;
		}
		return true;
	}

	private int ticketsNumber() {
		return Integer.parseInt(ticketsTextField.getText());
	}
	private int exchangeReserveTicketsNumber() {
		return Integer.parseInt(exchangeReservedTicketsTextField.getText());
	}
	private int exchangeDesiredTicketsNumber() {
		return Integer.parseInt(exchangeDesiredTicketsTextField.getText());
	}

	private void checkButtonActionPerformed(java.awt.event.ActionEvent evt) {
		availableTicketsLabel.setText("");
		resultField.setText("");
		try {
			if (!validateUserAndShowFields()) return;
			String boxOfficeID = showIDTextField.getText(0, 3);
			// get the root naming context
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			// Use NamingContextExt instead of NamingContext, part of the Interoperable naming Service.
			NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
			// resolve the Object Reference in Naming
			String objName = boxOfficeID;
			serviceImpl = MyServiceHelper.narrow(ncRef.resolve_str(objName));
			int availableTickets = serviceImpl.check(showIDTextField.getText());
			System.out.println("Obtained a handle on server object: " + serviceImpl);
			availableTicketsLabel.setText(availableTickets + " tickets");
		} catch (Exception e) {
			setResultMessgae(e.getMessage());
		}
	}

	private void reserveButtonActionPerformed(java.awt.event.ActionEvent evt) {
		resultField.setText("");
		try {
			if (!validateUserAndShowFields()) return;
			if (!validateTicketsField()) return;
			String boxOfficeID = showIDTextField.getText(0, 3);
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
			String objName = boxOfficeID;
			serviceImpl = MyServiceHelper.narrow(ncRef.resolve_str(objName));
			serviceImpl.reserve(userIDTextField.getText(), showIDTextField.getText(), ticketsNumber());
			resultField.setText("Reserved Successfully!");
		} catch (Exception e) {
			setResultMessgae(e.getMessage());
		}
	}

	private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {
		resultField.setText("");
		try {
			if (!validateUserAndShowFields()) return;
			if (!validateTicketsField()) return;
			String boxOfficeID = showIDTextField.getText(0, 3);
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
			String objName = boxOfficeID;
			serviceImpl = MyServiceHelper.narrow(ncRef.resolve_str(objName));
			serviceImpl.cancel(userIDTextField.getText(), showIDTextField.getText(), ticketsNumber());
			resultField.setText("Cancelled Successfully!");
		} catch (Exception e) {
			setResultMessgae(e.getMessage());
		}
	}

	private void exchangeButtonActionPerformed(java.awt.event.ActionEvent evt) {
		resultField.setText("");
		try {
			if (!validateUserField()) return;
			if (!validateExchangeFields()) return;
			String boxOfficeID = exchangeReservedShowTextField.getText(0, 3);
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
			String objName = boxOfficeID;
			serviceImpl = MyServiceHelper.narrow(ncRef.resolve_str(objName));
			serviceImpl.exchange(
					userIDTextField.getText(),
					exchangeReservedShowTextField.getText(),
					exchangeReserveTicketsNumber(),
					exchangeDesiredShowTextField.getText(),
					exchangeDesiredTicketsNumber()
			);
			resultField.setText("Exchanged Successfully!");
		} catch (Exception e) {
			setResultMessgae(e.getMessage());
		}
	}
	
	private void setResultMessgae(final String msg) {
		 SwingUtilities.invokeLater(new Runnable() {
             public void run() {
         		String result = msg;
        		String[] lines = msg.split("\n");
        		for (int i = 0; i < lines.length; i++) {
        			String line = lines[i];
        			if (line.trim().startsWith("Caused by: java.lang.IllegalStateException: ")) {
        				result = line.substring("Caused by: java.lang.IllegalStateException: ".length() - 1);
        				break;
        			}
        		}
        		resultField.setText(result);
             }
         });
	}

	/**
	 * Client application enrty point.
	 * 
	 * @param args
	 */
	public static void main(String args[]) {
		try {
			// create and initialize the ORB
			orb = ORB.init(args, null);
			java.awt.EventQueue.invokeLater(new Runnable() {
				public void run() {
					new MyServiceClient().setVisible(true);
				}
			});
		} catch (Exception e) {
			System.out.println("ERROR : " + e);
			e.printStackTrace(System.out);
		}
	} // end main

} // end class
